package com.Hsu.mq.mqserver.datacenter;

/**
 * @author Hsu琛君珩
 * @ClassName:DiskDataCenter
 * @date 2024-02-17
 * @apiNote
 * @Version: v1.0
 */

import com.Hsu.mq.common.MqException;
import com.Hsu.mq.mqserver.core.Binding;
import com.Hsu.mq.mqserver.core.Exchange;
import com.Hsu.mq.mqserver.core.MSGQueue;
import com.Hsu.mq.mqserver.core.Message;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

/**
 * 负责管理硬盘上的数据，包括消息的持久化存储和读取
 * 通过 MessageFileManager 类来操作硬盘上的消息文件，通过 DataBaseManager 来管理数据库中的元数据
 * 使用这个类管理所有硬盘上的数据
 * 1.数据库：交换机、队列、绑定
 * 2.数据文件：消息
 * 上层逻辑如果需要操作硬盘数据，统一通过这个类来使用。
 * 上层代码不关心当前数据是存储在数据库还是文件中的
 */
public class DiskDataCenter {
    //这个实例用来管局数据库中的数据
    private DataBaseManager dataBaseManager=new DataBaseManager();
    //这个实例用来管理数据文件中的数据
    private MessageFileManager messageFileManager=new MessageFileManager();

    public void init(){
        //针对两个实例进行初始化
        dataBaseManager.init();
        messageFileManager.init();//messageFileManager.init() 目前是空的状态，是方便后续扩展而调用的
    }

    //封装交换机操作
    public void insertExchange(Exchange exchange){
        dataBaseManager.insertExchange(exchange);
    }
    public void deleteExchange(String exchangeName){
        dataBaseManager.deleteExchange(exchangeName);
    }
    public List<Exchange> selectAllExchanges(){
        return dataBaseManager.selectAllExchanges();
    }

    //封装队列操作
    public void insertQueue(MSGQueue queue) throws IOException {
        dataBaseManager.insertQueue(queue);
        //创建队列同时，不仅要把队列对象写到数据库中，还需要创建出对应的目录和文件
        messageFileManager.createQueueFiles(queue.getName());
    }
    public void deleteQueue(String queueName) throws IOException {
        dataBaseManager.deleteQueue(queueName);
        //删除队列同时，不仅要把队列对象从数据库中删除，还需要创建出对应的目录和文件
        messageFileManager.createQueueFiles(queueName);
    }
    public List<MSGQueue> selectAllQueues(){
        return dataBaseManager.selectAllQueues();
    }

    //封装绑定操作
    public void insertBinding(Binding binding){
        dataBaseManager.insertBinding(binding);
    }
    public void deleteBinding(Binding binding){
        dataBaseManager.deleteBinding(binding);
    }
    public List<Binding> selectAllBindings(){
        return dataBaseManager.selectAllBindings();
    }

    //封装消息操作
    public void sendMessage(MSGQueue queue, Message message) throws IOException, MqException {
        messageFileManager.sendMessage(queue,message);
    }
    public void deleteMessage(MSGQueue queue,Message message) throws IOException, ClassNotFoundException, MqException {
        messageFileManager.deleteMessage(queue,message);
        //删除后可能要触发 gc
        if(messageFileManager.checkGC(queue.getName())){
            messageFileManager.gc(queue);
        }
    }
    public LinkedList<Message> loadAllMessageFromQueue(String queueName) throws IOException, MqException, ClassNotFoundException {
        return messageFileManager.loadAllMessageFromQueue(queueName);
    }
}
